package com.ytjj.qmyx.admin.service.imService.impl;

import com.alibaba.fastjson.JSON;
import com.ytjj.common.api.CommonResult;
import com.ytjj.common.constants.QueueConstants;
import com.ytjj.common.constants.im.ImRedisKeyConstant;
import com.ytjj.common.service.RedisService;
import com.ytjj.qmyx.admin.mapper.ImMessageInfoMapper;
import com.ytjj.qmyx.admin.mapper.ImSessionInfoMapper;
import com.ytjj.qmyx.admin.mapper.ImUserBindInfoMapper;
import com.ytjj.qmyx.admin.model.ImMessageInfo;
import com.ytjj.qmyx.admin.model.ImMessageInfoExample;
import com.ytjj.qmyx.admin.model.ImSessionInfo;
import com.ytjj.qmyx.admin.model.ImSessionInfoExample;
import com.ytjj.qmyx.admin.model.dto.ImMessageInfoDto;
import com.ytjj.qmyx.admin.model.dto.ImUserBindInfoDto;
import com.ytjj.qmyx.admin.model.response.im.ImMessageInfoResponse;
import com.ytjj.qmyx.admin.model.vo.ImMessageInfoVO;
import com.ytjj.qmyx.admin.service.imService.ImMessageInfoService;
import com.ytjj.qmyx.admin.utils.DateUtils;
import com.ytjj.qmyx.admin.utils.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ImMessageInfoServiceImpl implements ImMessageInfoService {

    @Resource
    private ImMessageInfoMapper imMessageInfoMapper;
    @Resource
    private ImSessionInfoMapper imSessionInfoMapper;
    @Autowired
    private RedisService redisService;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private ImUserBindInfoMapper imUserBindInfoMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     *  获取聊天历史信息
     * @param sessionId
     * @return
     */
    @Override
    public List<ImMessageInfoDto> getChatHistory(Integer sessionId, Integer isAll,String isAccess) {
        List<ImMessageInfoDto> result = new LinkedList<>();
        //获取当前会话信息
        ImSessionInfo imSessionInfo = imSessionInfoMapper.selectByPrimaryKey(sessionId);
        String customerId = imSessionInfo.getCustomerId();
        //通过当前客户标识获取全部的会话id
        List<Integer> sessionIds = imSessionInfoMapper.selectIdsByCustomerId(customerId);
        //如果传入isAll=1 则查全部聊天信息
        ImUserBindInfoDto imUserBindInfoDto = imUserBindInfoMapper.selectBySessionId(imSessionInfo.getCustomerId());
        String userName = "";
        if (null != imUserBindInfoDto && !StringUtils.isEmpty(imUserBindInfoDto.getUserName())){
            userName = imUserBindInfoDto.getUserName();
        }
        if (null != isAll && 1 == isAll){
            result = imMessageInfoMapper.getAllDTOChatHistory(sessionIds, customerId, isAll);
            String finalUserName = userName;
            result.stream().forEach(item -> {
                //给每一条信息赋予发送者名称
                if (item.getSelfFlag().equals(1)) {
                    item.setName(null == item.getName() ? item.getSendUserId() : item.getName());
                }else {
                    item.setName(StringUtils.isEmpty(finalUserName) ? item.getSendUserId() : finalUserName);
                }
            });
            return result.stream().sorted(Comparator.comparing(ImMessageInfoDto::getId)).collect(Collectors.toList());
        }
        //当客户 客服和系统消息 都需要来更新这个redis值
        String redisKey = ImRedisKeyConstant.SESSION_HISTORY_MESSAGES + sessionId;
        Set<Object> historyMessageList = redisService.sGet(redisKey);
        historyMessageList.clear();//todo 结束初步测试后删除1==2条件
        if (historyMessageList.isEmpty()) {
            //判断是否从来访信息的访问记录进来
            if (StringUtils.isEmpty(isAccess)){
                result = imMessageInfoMapper.getAllDTOChatHistory(sessionIds, customerId, null);
            }else {
                result = imMessageInfoMapper.getChatHistory(sessionId, customerId);
            }
            String finalUserName = userName;
            result.stream().forEach(item -> {
                //给每一条信息赋予发送者名称
                if (item.getSelfFlag().equals(1)) {
                    item.setName(null == item.getName() ? item.getSendUserId() : item.getName());
                }else {
                    item.setName(StringUtils.isEmpty(finalUserName) ? item.getSendUserId() : finalUserName);
                }
                //存入redis中
                redisService.sSetAndTime(redisKey, 30 * 3600 * 24 , JSON.toJSONString(item));
            });
        } else {
            Iterator<Object> iterator = historyMessageList.iterator();
            while (iterator.hasNext()) {
                String messageStr = (String) iterator.next();
                ImMessageInfoDto messageInfo = com.alibaba.fastjson.JSONObject.parseObject(messageStr, ImMessageInfoDto.class);
                result.add(messageInfo);
            }
        }
        //更新聊天记录为已读
        updateMessageStatusIsRead(sessionId,imSessionInfo.getServiceId());
        return result.stream().sorted(Comparator.comparing(ImMessageInfoDto::getId)).collect(Collectors.toList());

    }

    /**
     * 更新会话下的消息状态为已读
     * @param sessionId
     */
    private void updateMessageStatusIsRead(Integer sessionId,String serviceId) {
        try {
            imMessageInfoMapper.updateMessageStatusIsRead(sessionId);
            imMessageInfoMapper.updateIsRead(serviceId);
        } catch (Exception e) {
            log.error("===更新session下的message status is read err==={}", e);
        }
    }

    /**
     * 客服撤回消息-只有2分钟以内的消息能撤回
     * @param imMessageInfoVO
     * @return
     */
    @Override
    public CommonResult messageRecall(ImMessageInfoVO imMessageInfoVO) {
        ImMessageInfo imMessageInfo = imMessageInfoMapper.selectByPrimaryKey(imMessageInfoVO.getId());
        //消息能撤回的最大时间阈值
        Date canRecallMaxdate = DateUtils.getFutureDate(imMessageInfo.getCreateTime(), 2);
        if (canRecallMaxdate.compareTo(new Date()) < 0) {
            return CommonResult.failed("消息已发出超过2分钟，不能撤回");
        }
        int count = imMessageInfoMapper.deleteByPrimaryKey(imMessageInfo.getId());
        if (count > 0) {
            //需要做一个标识，让im系统触发给客户发送消息，撤回界面消息
            Map<String, String> mq_message = new HashMap<>();
            mq_message.put("receiveUserId", imMessageInfo.getReceiveUserId());
            mq_message.put("sessionId", String.valueOf(imMessageInfo.getSessionId()));
            mq_message.put("id", String.valueOf(imMessageInfo.getId()));
            mq_message.put("type",QueueConstants.IM_RECALL_QUEUE);
//            rabbitTemplate.convertAndSend(QueueConstants.IM_RECALL_QUEUE, mq_message);
            stringRedisTemplate.convertAndSend(QueueConstants.IM_ADMIN_NOTIFY, JSON.toJSONString(mq_message));
            return CommonResult.success("成功撤回");
        }
        return CommonResult.failed("撤回失败");
    }

    /**
     * 获取历史消息
     * @param userId
     * @return
     */
    @Override
    public List<ImMessageInfoResponse> queryUserHistoryMessage(String userId) {
        List<ImSessionInfo> sessionList = querySessionListByCustomerId(userId);
        List<ImMessageInfoResponse> result = new LinkedList<>();
        sessionList.stream().forEach(session -> {
            ImMessageInfoExample example = new ImMessageInfoExample();
            example.createCriteria().andSessionIdEqualTo(session.getId());
            example.setOrderByClause("createTime asc");
            List<ImMessageInfo> imMessageInfoList = imMessageInfoMapper.selectByExample(example);
            imMessageInfoList.stream().forEach(item -> {
                ImMessageInfoResponse response = ImMessageInfoResponse.builder()
                        .sendUserId(item.getSendUserId())
                        .createTime(item.getCreateTime())
                        .receiveUserId(item.getReceiveUserId())
                        .messageType(item.getMessageType())
                        .content(item.getContent())
                        .selfFlag(userId.equals(item.getSendUserId()) ? 1 : 0)
                        .build();
                result.add(response);
            });
        });
        return result;
    }

    /**
     * 获取用户未读信息
     * @param receiveUserId
     * @return
     */
    @Override
    public int selectUnreadMessage(String receiveUserId) {
        return imMessageInfoMapper.selectUnreadMessage(receiveUserId);
    }


    /**
     * 根据客户id获取所有会话记录
     * @param customerId
     * @return
     */
    public List<ImSessionInfo> querySessionListByCustomerId(String customerId) {
        ImSessionInfoExample example = new ImSessionInfoExample();
        example.createCriteria().andCustomerIdEqualTo(customerId);
        example.setOrderByClause("createTime asc");
        List<ImSessionInfo> list = imSessionInfoMapper.selectByExample(example);
        return list;
    }
}
